﻿#include "dft.hpp"

namespace cuda
{
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>	Scale Signal </summary>
/// <remarks>	Quan, 6/18/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////
__global__ 
void __scale(float2* signal,		//Signal
	int nRows,						//Number of Rows
	int nCols,						//Number of Cols
	int scale)						//Scaling factor
{
	int idx = threadIdx.x + blockIdx.x*blockDim.x;
	if(idx < nCols*nRows)
	{
		signal[idx].x = signal[idx].x / scale;
		signal[idx].y = signal[idx].y / scale;
	}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void scale(float2* signal,			//Signal
	int nRows,						//Number of Rows
	int nCols,						//Number of Cols
	int scale)						//Scaling factor
{
	__scale config(nRows*nCols, 1, 256, 1, 0)	\
		(signal, nRows, nCols, scale);
	cudaThreadSynchronize();
	cudaGetLastError();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>	Fourier Transform </summary>
/// <remarks>	Quan, 6/18/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////
void dft(
	float2* src,	
	float2* dst,	
	int nRows,
	int nCols,
	int flag)
{
	/// <summary>	Prepare for Fourier Transform </summary>
	cufftHandle plan;
	cufftPlan2d(&plan, nCols, nRows, CUFFT_C2C);

	/// <summary>	Perform Fourier Transform </summary>
	switch(flag)
	{
	/// <summary>	Forward Fourier Transform </summary>
	case DFT_FORWARD:		
		cufftExecC2C(plan, 
			(cufftComplex*)(src),
			(cufftComplex*)(dst),
			CUFFT_FORWARD);
		break;
	
	/// <summary>	Inverse Fourier Transform </summary>
	case DFT_INVERSE:		
		cufftExecC2C(plan, 
			(cufftComplex*)(src),
			(cufftComplex*)(dst),
			CUFFT_INVERSE);
		
		/// <summary>	Scale the output </summary>
		scale(dst, nRows, nCols, nRows*nCols);
		/// CUFFT performs un-normalized FFTs; that is, performing a forward FFT on an input
		/// data set followed by an inverse FFT on the resulting set yields data that is equal to the
		///	input scaled by the number of elements. Scaling either transform by the reciprocal of the
		///	size of the data set is left for the user to perform as seen ﬁt.
		break;
	default:
		break;
	}

}
}